/**
*  \file adc.c
*
*  \brief ADC sample function
*
*  \author dajin.li  <dajin.li@linde-china.cn>
*
*/

/*===============================================[ private includes  ]================================================*/
#include <xmc4500/adc_hw.h>
#include <xmc4500/io.h>
#include <xmc4500/processor.h>
#include <xmc4500/types_local.h>
#include "../sched/sched.h"
#include "../pal/pal_mem.h"



/*===============================================[ private defines   ]================================================*/

/*===============================================[ private datatypes ]================================================*/

/*===============================================[ private variables ]================================================*/

/*===============================================[ private functions ]================================================*/

/*================================================[ inline functions ]================================================*/

/*================================================[ public functions ]================================================*/


void adc_hardware_init(void)
{
    /* AD Clock Trigger 10kHz - CCU40_43*/

    SCU_GENERAL->CCUCON |=(1 << SCU_GENERAL_CCUCON_GSC40_Pos); /*CCU40_CC43 global enable*/
    CCU40->GIDLC |= (1 << CCU4_GIDLC_CS3I_Pos);                /*CC43 Idle clear*/
    CCU40->GIDLC |= (1 << CCU4_GIDLC_SPRB_Pos);                /*Prescaller Run Bit set*/
    CCU40_CC43->PSC = 1;                                       /*Prescaller select->0*/
    CCU40_CC43->TCSET = 1;                                     /*Timer Run Bit set*/
    CCU40_CC43->INTE = 1;                                      /*Period Match*/
    CCU40_CC43->SRS = 2;                                       /*Service request 2 for AD trigger Forward to CC43SR2*/
    CCU40_CC43->PRS = 0x176f;                                  /*Period set = 120e6 Hz / (2 * 10kHz) - 1*/
    CCU40_CC43->CRS = 0xbb7;                                   /*Duty Sycle set*/
    CCU40->GCSS |= (1 << CCU4_GCSS_S3SE_Pos);                  /*Shadow transfer request*/

    /* Configure AD's*/

    CLR_BIT( VADC->CLC, VADC_CLC_DISR_Pos);                    /*enable the module*/      
    SET_BIT( VADC->GLOBCFG, VADC_GLOBCFG_DIVWC_Pos);           /*enable write access*/
    VADC->GLOBCFG = 3;                                         /*fADCI = fADC / 4*/
    CLR_BIT( VADC->GLOBCFG, VADC_GLOBCFG_DIVWC_Pos);           /*disable write access*/
    VADC->GLOBICLASS[0] = 0;                                   /*12bit conversion, sample time 2/fADCI*/
    VADC->GLOBICLASS[1] = 0;                                   /*12bit conversion, sample time 2/fADCI*/
    VADC->GLOBBOUND = 0;                                       /*boundary value for limit checking*/

    VADC_G0->ARBCFG = 0;                                       /*arbitration configuration register*/
    VADC_G0->BOUND = 0;                                        /*Boundary select register*/
    VADC_G0->EMUXCTR = 0x40000000;                             /*External multiplexer control register,
                                                                external multiplexer channel selection style, channel number*/
    VADC_G0->ICLASS[0] = 0;                                    /*Input class register 0, group 0, 12 bit conversion, sample time 2/fADCI*/
    VADC_G0->ICLASS[1] = 0;                                    /*Input class register 1, group 0, 12 bit conversion, sample time 2/fADCI*/
    VADC_G0->ARBCFG = 0x00000003;                              /*Arbitration configuration register, Group 0 ANONS = 11B: normal operation*/

    VADC_G1->ARBCFG = 0;
    VADC_G1->BOUND = 0;
    VADC_G1->EMUXCTR = 0x40000000;
    VADC_G1->ICLASS[0] = 0;
    VADC_G1->ICLASS[1] = 0;
    VADC_G1->ARBCFG = 0x00000003;

    VADC_G2->ARBCFG = 0;
    VADC_G2->BOUND = 0;
    VADC_G2->EMUXCTR = 0x40000000;
    VADC_G2->ICLASS[0] = 0;
    VADC_G2->ICLASS[1] = 0;
    VADC_G2->ARBCFG = 0x00000003;

    VADC_G3->ARBCFG = 0;
    VADC_G3->BOUND = 0;
    VADC_G3->EMUXCTR = 0x40000000;
    VADC_G3->ICLASS[0] = 0;
    VADC_G3->ICLASS[1] = 0;
    VADC_G3->ARBCFG = 0x00000003;

    SET_BIT(VADC->GLOBCFG, VADC_GLOBCFG_SUCAL_Pos);              /*Initiate the start-up calibration phase*/

    /* Configure individual AD Channels*/

    /* ADC Group 0*/

    VADC_G0->CHASS = 0xFF;                                      /* Channel 0-7 is a priority channel within group 0*/

    /*Channel control registers*/
    
    /*ICLSEL,  [1:0],  Input Class Select, 01B Use group-specific class 1*/
    /*0        [3:2]   Reserved,         write 0, read as 0*/
    /*BNDSELL  [5:4]   Lower Boundary Select, 00B Use group-specific boundary 0*/
    /*BNDSELU  [7:6]   Upper Boundary Select, 01B Use group-specific boundary 1*/
    /*CHEVMODE [9:8]   Channel Event Mode,    00B Never*/
    /*SYNC     10      Synchronization Request, 0B No synchroniz. request, standalone operation*/
    /*REFSEL   11      Reference Input Selection, 0B Standard reference input VAREF*/
    /*0        [15:12] Reserved, write 0, read as 0*/
    /*RESREG   [19:16] Result Register,0101B Store result in group result register G0RES5*/
    /*RESTBS   20      Result Target for Background Source, 0B Store results in the selected group result register*/
    /*RESPOS   21      Result Position, 1B Store results right-aligned*/
    /*0        [27:22] Reserved, write 0, read as 0*/
    /*BWDCH    [29:28] Broken Wire Detection Channel, 00B Select VAGND*/
    /*BWDEN    30      Broken Wire Detection Enable, 0B Normal operation*/
    /*0        31      Reserved, write 0, read as 0  */
    /*put auto scan to group 0*/
    
    VADC_G0->CHCTR[0] = 0x00280040; /*P14.0 VADC.G0CH0, unused*/
    VADC_G0->CHCTR[1] = 0x002f0041; /*P14.1 VADC.G0CH1, TEMP_MOT_A_IN_A_CPU_V*/
    VADC_G0->CHCTR[2] = 0x00290040; /*P14.2 VADC.G0CH2, +5V_EXTERNAL_SENSORS_A_CPU_V*/
    VADC_G0->CHCTR[3] = 0x00210041; /*P14.3 VADC.G0CH3, +12V_DRIVER_SUPPLY*/
    VADC_G0->CHCTR[4] = 0x00230041; /*P14.4 VADC.G0CH4, unused*/
    VADC_G0->CHCTR[5] = 0x002a0040; /*P14.5 VADC.G0CH5, DC_LINK_+_IN_A_CPU_V*/
    VADC_G0->CHCTR[6] = 0x002d0041; /*P14.6 VADC.G0CH6, ACCELERATOR_1_IN_A_CPU_V*/
    VADC_G0->CHCTR[7] = 0x00270040; /*P14.7 VADC.G0CH7, +13.7V_SUPPLY_A_CPU_V*/

    /*Group 0 Result Control Reg.*/

    /*0      [15:0]     Reserved, write 0, read as 0*/
    /*DRCTR  [19:16]    Data Reduction Control*/
    /*DMM    [21:20]    Data Modification Mode 00B Standard data reduction (accumulation)*/
    /*0      [23:22]    Reserved, write 0, read as 0*/
    /*WFR    24         Wait-for-Read Mode Enable 0B Overwrite mode*/
    /*FEN    [26:25]    FIFO Mode Enable 01B Part of a FIFO structure: copy each new valid result*/
    /*0      [30:27]    Reserved, write 0, read as 0*/
    /*SRGEN  31         Service Request Generation Enable 0B No service request*/    
    VADC_G0->RCR[0]  = 0x02000000;      /*unused, is a queue*/
    VADC_G0->RCR[1]  = 0x00000000;      /*unused*/
    
    VADC_G0->RCR[2]  = 0x02000000;      /*unused, is a queue*/
    VADC_G0->RCR[3]  = 0x00000000;      /*unused*/
    
    VADC_G0->RCR[4]  = 0x00000000;      /*unused*/
    VADC_G0->RCR[5]  = 0x00000000;      /*unused*/
    VADC_G0->RCR[6]  = 0x00000000;      /*unused*/ 
    
    VADC_G0->RCR[7]  = 0x00000000;      /*unused*/
    VADC_G0->RCR[8]  = 0x00000000;      /*unused*/
    VADC_G0->RCR[9]  = 0x00000000;      /*unused*/
    VADC_G0->RCR[10] = 0x00000000;      /*unused*/
    
    VADC_G0->RCR[11] = 0x00000000;     
    
    VADC_G0->RCR[12] = 0x02000000;      /*ACCELERATOR_1_IN_A_CPU_V, is a queue*/
    VADC_G0->RCR[13] = 0x00000000;      /*ACCELERATOR_1_IN_A_CPU_V*/
    
    VADC_G0->RCR[14] = 0x02000000;      /*TEMP_MOT_A_IN_A_CPU_V, is a queue*/
    VADC_G0->RCR[15] = 0x00000000;      /*TEMP_MOT_A_IN_A_CPU_V*/

    SET_BIT(VADC_G0->QMR0, VADC_G_QMR0_FLUSH_Pos); /*Queue 0 Mode Register, Group 0 Flush Queue,Clear all queue entries*/

    /*Queue 0 Input Register, Group 0*/
    
    /*REQCHNR [4:0]  Request Channel Number:Defines the channel number to be converted*/
    /*RF      5      Refill, 1B Automatic refill, */
    /*ENSI    6      Enable Source Interrupt, No request source interrupt*/
    /*EXTR    7      External Trigger, 1B A valid queue entry waits for a trigger event to
                     occur before issuing a conversion request.*/
    /*0       [31:8] Reserved, write 0, read as 0*/
    /*put chanele to the queue*/
    
    VADC_G0->QINR0 = 0xa1;                      /* Enable trigger event, refill, channel 1 to queue*/
    VADC_G0->QINR0 = 0x23;                      /*Channel 3 to the queue*/
    VADC_G0->QINR0 = 0x24;                      /*Channel 4 to the queue*/
    VADC_G0->QINR0 = 0x26;                      /*Channel 6 to the queue*/
    VADC_G0->QINR0 = 0x21;                      /*Channel 1 to the queue*/
    VADC_G0->QINR0 = 0x23;                      /*Channel 3 to the queue*/
    VADC_G0->QINR0 = 0x24;                      /*Channel 4 to the queue*/
    VADC_G0->QINR0 = 0x26;                      /*Channel 6 to the queue*/

    /*Queue 0 Source Control Register*/
    
    VADC_G0->QCTRL0 = 0x0000C000;               /* Trigger source A, rising edge*/
    /*Queue 0 Mode Register, Group 0*/
    /*ENGT  [1:0]  Enable Gate,*/
    /*ENTR   2     Enable External Trigger*/
    VADC_G0->QMR0 = 0x05;

    /*Autoscan Source Channel Select Register*/
    /*CHSEL [7:0]   Channel Selection 1B This channel is part of the scan sequence*/
    /*0     [31:8]  Reserved, write 0, read as 0*/
    VADC_G0->ASSEL = 0xa5;
    /*Autoscan Source Control Register, Group 0*/
    VADC_G0->ASCTRL = 0x0000C000;

    /*Autoscan Source Mode Register,*/
    VADC_G0->ASMR = 0x05;
    /*Arbitration Priority Register*/
    VADC_G0->ARBPR |= 0x03000000;

    /* ADC Group 1*/

    VADC_G1->CHASS = 0xF3;                      /* Assign all Group 0 Priority Channels*/

    VADC_G1->CHCTR[0] = 0x00230040;            /*P14.8 VADC.G1CH0, STEER_ANGLE_B_IN_A_CPU_V*/ 
    VADC_G1->CHCTR[1] = 0x002b0040;            /*P14.9 VADC.G1CH1, RESERVE_2_IN_A_CPU_V*/
    VADC_G1->CHCTR[2] = 0x00000000;
    VADC_G1->CHCTR[3] = 0x00000000;
    VADC_G1->CHCTR[4] = 0x00270040;            /*P14.12 VADC.G1CH4, TEMP_MOT_B_IN_A_CPU_V*/ 
    VADC_G1->CHCTR[5] = 0x002a0040;            /*P14.13 VADC.G1CH5, CURRENT_CUT-OFF_ISO_VALVE_A_CPU_V*/
    VADC_G1->CHCTR[6] = 0x002f0040;            /*P14.14 VADC.G1CH6, ACCELERATOR_2_IN_A_CPU_V*/
    VADC_G1->CHCTR[7] = 0x00290040;            /*P14.15 VADC.G1CH7, CURRENT_MAIN_CONTACTOR_A_CPU_V*/

    VADC_G1->RCR[0]  = 0x02000000;               /* FIFO Result registers*/
    VADC_G1->RCR[1]  = 0x02000000;
    VADC_G1->RCR[2]  = 0x02000000;
    VADC_G1->RCR[3]  = 0x00000000;               /* Configure all other non FIFO result registers*/

    VADC_G1->RCR[4]  = 0x00000000;               /* Configure all other non FIFO result registers*/
    VADC_G1->RCR[5]  = 0x00000000;
    VADC_G1->RCR[6]  = 0x00000000;
    VADC_G1->RCR[7]  = 0x00000000;
    VADC_G1->RCR[8]  = 0x00000000;
    VADC_G1->RCR[9]  = 0x00000000;
    VADC_G1->RCR[10] = 0x00000000;
    VADC_G1->RCR[11] = 0x00000000;

    VADC_G1->RCR[12] = 0x02000000;              /* FIFO Result registers*/
    VADC_G1->RCR[13] = 0x02000000;
    VADC_G1->RCR[14] = 0x02000000;
    VADC_G1->RCR[15] = 0x00000000;

    SET_BIT(VADC_G1->QMR0, VADC_G_QMR0_FLUSH_Pos);
    VADC_G1->QINR0 = 0xa0;                          /* Enable trigger event, refill, channel*/
    VADC_G1->QINR0 = 0x21;
    VADC_G1->QINR0 = 0x20; 
    VADC_G1->QINR0 = 0x21;
    VADC_G1->QINR0 = 0x20;
    VADC_G1->QINR0 = 0x21;
    VADC_G1->QINR0 = 0x20;
    VADC_G1->QINR0 = 0x61;                          /* Enable source interrupt*/

    VADC_G1->QCTRL0 = 0x0000C000;                   /* Trigger source A, rising edge*/
    VADC_G1->QMR0 = 0x05;
    VADC_G1->SEVNP = 0x03;                          /* SEV0NP = 3, for queued source interrupt*/

    VADC_G1->ASSEL = 0xf0;
    VADC_G1->ASCTRL = 0x0000C000;
    VADC_G1->ASMR = 0x05;
    VADC_G1->ARBPR |= 0x03000000;

    /* ADC Group 2*/

    VADC_G2->CHASS = 0x0c;                      /* Assign all Group 0 Priority Channels*/

    VADC_G2->CHCTR[0] = 0x00000000;
    VADC_G2->CHCTR[1] = 0x00000000;              
    VADC_G2->CHCTR[2] = 0x002f0040;             /*P15.2 VADC.G2CH2, RESERVE_1_IN_A_CPU_V*/
    VADC_G2->CHCTR[3] = 0x00230040;             /*P15.3 VADC.G2CH3, STEER_ANGLE_A_IN_A_CPU_V*/
    VADC_G2->CHCTR[4] = 0x00000000;
    VADC_G2->CHCTR[5] = 0x00000000;
    VADC_G2->CHCTR[6] = 0x00000000;
    VADC_G2->CHCTR[7] = 0x00000000;

    VADC_G2->RCR[0] = 0x02000000;               /* FIFO Result registers*/
    VADC_G2->RCR[1] = 0x02000000;
    VADC_G2->RCR[2] = 0x02000000;
    VADC_G2->RCR[3] = 0x00000000;               /* Configure all other non FIFO result registers*/

    VADC_G2->RCR[4] = 0x00000000;               /* Configure all other non FIFO result registers*/
    VADC_G2->RCR[5] = 0x00000000;
    VADC_G2->RCR[6] = 0x00000000;
    VADC_G2->RCR[7] = 0x00000000;
    VADC_G2->RCR[8] = 0x00000000;
    VADC_G2->RCR[9] = 0x00000000;
    VADC_G2->RCR[10] = 0x00000000;
    VADC_G2->RCR[11] = 0x00000000;

    VADC_G2->RCR[12] = 0x02000000;              /*  FIFO Result registers*/
    VADC_G2->RCR[13] = 0x02000000;
    VADC_G2->RCR[14] = 0x02000000;
    VADC_G2->RCR[15] = 0x00000000;

    SET_BIT(VADC_G2->QMR0, VADC_G_QMR0_FLUSH_Pos);
    VADC_G2->QINR0 = 0xa2;                          /* Enable trigger event, refill, channel*/
    VADC_G2->QINR0 = 0x23;
    VADC_G2->QINR0 = 0x22;
    VADC_G2->QINR0 = 0x23;
    VADC_G2->QINR0 = 0x22;
    VADC_G2->QINR0 = 0x23;
    VADC_G2->QINR0 = 0x22;
    VADC_G2->QINR0 = 0x23;                          /* Enable source interrupt*/

    VADC_G2->QCTRL0 = 0x0000C000;                   /* Trigger source A, rising edge*/
    VADC_G2->QMR0 = 0x05;
    VADC_G2->ARBPR |= 0x01000000;

    /* ADC Group 3*/

    VADC_G3->CHASS = 0x0F;                      /* Assign all Group 0 Priority Channels*/

    VADC_G3->CHCTR[0] = 0x002f0041;              /*P15.8 VADC.G3CH0, unused*/
    VADC_G3->CHCTR[1] = 0x00290041;              /*P15.9 VADC.G3CH1, KEY_SWITCH_IN_A_CPU_V*/
    VADC_G3->CHCTR[2] = 0x00230041;              /*P14.8 VADC.G3CH2, STEER_ANGLE_B_IN_A_CPU_V*/
    VADC_G3->CHCTR[3] = 0x00240041;              /*P14.9 VADC.G3CH3, RESERVE_2_IN_A_CPU_V*/
    VADC_G3->CHCTR[4] = 0x00000000;
    VADC_G3->CHCTR[5] = 0x00000000;
    VADC_G3->CHCTR[6] = 0x00000000;
    VADC_G3->CHCTR[7] = 0x00000000;

    VADC_G3->RCR[0]  = 0x02000000;
    VADC_G3->RCR[1]  = 0x02000000;
    VADC_G3->RCR[2]  = 0x02000000;
    VADC_G3->RCR[3]  = 0x00000000;
    VADC_G3->RCR[4]  = 0x00000000;
    VADC_G3->RCR[5]  = 0x00000000;
    VADC_G3->RCR[6]  = 0x00000000;
    VADC_G3->RCR[7]  = 0x00000000;
    VADC_G3->RCR[8]  = 0x00000000;
    VADC_G3->RCR[9]  = 0x00000000;
    VADC_G3->RCR[10] = 0x00000000;
    VADC_G3->RCR[11] = 0x00000000;
    VADC_G3->RCR[12] = 0x02000000;
    VADC_G3->RCR[13] = 0x02000000;
    VADC_G3->RCR[14] = 0x02000000;
    VADC_G3->RCR[15] = 0x00000000;


    SET_BIT(VADC_G3->QMR0, VADC_G_QMR0_FLUSH_Pos);
    VADC_G3->QINR0 = 0xa2;                          /* Enable trigger event, refill, channel*/
    VADC_G3->QINR0 = 0x23;
    VADC_G3->QINR0 = 0x22;
    VADC_G3->QINR0 = 0x23;
    VADC_G3->QINR0 = 0x22;
    VADC_G3->QINR0 = 0x23;
    VADC_G3->QINR0 = 0x22;
    VADC_G3->QINR0 = 0x23;                          /* Enable source interrupt*/

    VADC_G3->QCTRL0 = 0x0000C000;                   /* Trigger source A, rising edge*/
    VADC_G3->QMR0 = 0x05;

    VADC_G3->ASSEL = 0x03;
    VADC_G3->ASCTRL = 0x0000C000;
    VADC_G3->ASMR = 0x05;
    VADC_G3->ARBPR |= 0x03000000;

    NVIC_SetPriority(VADC0_G1_3_IRQn, VADC0_G1_3_INT_PRI);       /* AD motor control Interrupt Interrupt*/

}



